/* getDiffPars.c                             (\(\
 * Jannis Teunnissen and Florian Speelman    (='.')
 * Scientific Computing - spring 2010        o(_")")
 */

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <math.h>
#include <mpi.h>
#include "getDiffPars.h"

void getDiffPars(int argc, char *argv[], diffPars *p) {
    p->nOutputs = 0;
    p->imgOutput = 0;
    p->loadBalance = 0;
    p->dx = 0.1;
    p->dt = 0.1;
    p->D = 1.;
    p->maxTime = 1.;
    p->threshold = 1e-5;
	p->checkInterval = 1;
	
    int ch;
    while ((ch = getopt(argc, argv, "o:i:x:t:D:T:gbe:")) != -1) {
        switch(ch) {
        case 'o': p->nOutputs = strtol(optarg, 0, 10); break;
        case 'i': p->checkInterval = strtol(optarg, 0, 10); break;
        case 'x': p->dx = strtod(optarg, 0); break;
        case 't': p->dt = strtod(optarg, 0); break;
        case 'D': p->D = strtod(optarg, 0); break;
		case 'e': p->threshold = strtod(optarg, 0); break;
        case 'T': p->maxTime = strtod(optarg, 0); break;
        case 'g': p->imgOutput = 1; break;
        case 'b': p->loadBalance = 1; break;
        }
    }
    p->totalPoints = (int) (round(1. / p->dx) + 1);
    
    printf("Parameters:\
            \n nOutputs (-o)    \t%d\
            \n imgOutput (-g)   \t%d\
            \n loadBalance (-b) \t%d\
            \n dx (-x)          \t%.2e\
            \n dt (-t)          \t%.2e\
            \n D (-D)           \t%.2e\
			\n threshold (-e)   \t%.2e\
			\n checkInterval (-i)\t%d\
            \n maxTime (-T)     \t%.2e\n\n",
            p->nOutputs,
            p->imgOutput,
            p->loadBalance,          
            p->dx,
            p->dt,
            p->D,
			p->threshold,
			p->checkInterval,
            p->maxTime);
}

void initPars(int argc, char *argv[], diffPars *p, MPI_Comm *commPtr) {
	int ntasks, myrank, one = 1, zero = 0;
    
	MPI_Comm_size(MPI_COMM_WORLD, &ntasks);
	MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    
	MPI_Cart_create(MPI_COMM_WORLD, one, &ntasks, &zero, one, commPtr);
    
	if(myrank == 0) getDiffPars(argc, argv, p);

	MPI_Datatype diffpMPI;
	MPI_Datatype ptype[2] = {MPI_INT, MPI_DOUBLE};
	MPI_Aint pdisp[2] = {(void*)&p->nOutputs - (void*)p, (void*)&p->dx - (void*)p};
	int pblocklen[2] = {5, 5};
	MPI_Type_create_struct(2, pblocklen, pdisp, ptype, &diffpMPI);
    
	MPI_Type_commit(&diffpMPI);
	MPI_Bcast(p, 1, diffpMPI, 0, *commPtr);
	MPI_Type_free(&diffpMPI);
}
